package StatuSync::User;
use strict;

# a user model

use base qw(StatuSync::Log);

use DBI;
use Net::Twitter::Lite;
use base qw(Class::Accessor);

sub dbname { "statusync.sqlite" }
sub table { "user" }
sub fields { qw(id email password tw_username tw_id vk_email vk_password) }

__PACKAGE__->mk_accessors(__PACKAGE__->fields);

__PACKAGE__->init();

my $dbh;

sub dbh {
	my $class = shift;
	unless ($dbh) {
		$dbh = DBI->connect("dbi:SQLite:dbname=".$class->dbname, "", "",
			{ RaiseError => 1, AutoCommit => 1 });
	}
	return $dbh;
}

sub query {
	my $self = shift;
	my ($sql, @bind) = @_;
	$self->debug($sql, \@bind);
	my $sth = $self->dbh->prepare_cached($sql);
	$sth->execute( @bind );
	return $sth;
}

sub init {
	my $class = shift;
	my $sql = "CREATE TABLE IF NOT EXISTS ".$class->table." (
		id INTEGER PRIMARY KEY,
		email TEXT UNIQUE NOT NULL,
		password TEXT,
		tw_username TEXT,
		tw_id TEXT,
		vk_email TEXT,
		vk_password TEXT
	)";
	$class->query($sql);
	return $class;
}


sub create {
	my $class = shift;
	my %args = %{shift||{}};
	my $sql = sprintf "INSERT INTO %s (%s) VALUES (%s)",
		$class->table, join(", ", $class->fields), join(", ", map { "?" } $class->fields);
	$class->query( $sql, @args{$class->fields} );
	$args{id} = $class->dbh->last_insert_id('','','',''),
	return $class->new({ map { $_ => $args{$_} } $class->fields });
}

sub update {
	my $self = shift;
	my %args = %{shift||{}};
	my @bind;
	my $sql = sprintf "UPDATE %s SET %s WHERE id = ?", $self->table,
		join(", ", map { push @bind => $args{$_}; $self->$_($args{$_}); "$_ = ?" }
			grep { $_ ne 'id' && exists $args{$_} } $self->fields);
	$self->query( $sql, @bind, $self->id );
	return $self;
}

sub delete {
	my $self = shift;
	ref($self) or die "delete is an instance method";
	my $sql = sprintf "DELETE FROM %s WHERE id = ?", $self->table;
	$self->query($sql, $self->id);
	return;
}

sub search {
	my $class = shift;
	my %args = %{shift||{}};
	my $sql = sprintf "SELECT * FROM %s", $class->table;
	my @bind;
	my %where = map { $_ => $args{$_} } grep { exists $args{$_} } $class->fields;
	$sql .= " WHERE ".join(" AND ", map { push @bind => $where{$_}; "$_ = ?" } keys %where) if %where;
	$sql .= " ORDER BY ".$args{order} if $args{order};
	$sql .= " LIMIT ".$args{limit} if $args{limit};
	my $sth = $class->query($sql, @bind);
	return map { $class->new($_) } @{ $sth->fetchall_arrayref({}) };
}

sub find {
	my $class = shift;
	my @result = $class->search(@_) or return;
	return $result[0];
}

sub get_twitter_id {
	my $self = shift;

	$self->debug('self=',$self);
	my $twuser = Net::Twitter::Lite->new->show_user($self->tw_username);
	$self->debug('twuser=',$twuser);

	$twuser->{id} or $self->die("cannot get user id (".$self->tw_username.")");

	$self->tw_id( $twuser->{id} );
	return $self->tw_id;
}


1;

